﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace MemoryMonitor
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 属性
        private BackgroundWorker Worker { get; set; }
        private ProcessInfo ProInfo { get; set; }
        #endregion

        #region 构造初始化

        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            Worker = new BackgroundWorker();
            Worker.WorkerSupportsCancellation = true;
            Worker.DoWork += Worker_DoWork;
            Worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

            CallRefresh();
        }

        private void Refresh()
        {
            ComboBoxProcessName.ItemsSource = Process.GetProcesses().
                Select(x => new ProcessInfo() { Id = x.Id, ProcessName = x.ProcessName }).
                OrderBy(x => x.ProcessName).ToList();
            ButtonMonitor.IsEnabled = true;
            ButtonCancelMonitor.IsEnabled = false;
            ComboBoxProcessName.IsEnabled = true;
        }

        #endregion

        #region 事件

        private delegate void RefreshDelegate();

        private void CallRefresh()
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Background, new RefreshDelegate(Refresh));
        }

        #endregion

        private void MonitorClick(object sender, RoutedEventArgs e)
        {
            ProInfo = ComboBoxProcessName.SelectedItem as ProcessInfo;
            if (ProInfo != null)
            {
                if (!Worker.IsBusy)
                {
                    ButtonMonitor.IsEnabled = false;
                    ButtonCancelMonitor.IsEnabled = true;
                    ComboBoxProcessName.IsEnabled = false;
                    Worker.RunWorkerAsync();
                }
            }
        }



     

        void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void Worker_DoWork(object sender, DoWorkEventArgs e)
        {

            while (true)
            {
                if (Worker.CancellationPending)
                {
                    CallRefresh();
                    break;
                }
                else
                {
                    try
                    {
                        var p = Process.GetProcessById(ProInfo.Id);
                        var pf1 = new PerformanceCounter("Process", "Working Set - Private", p.ProcessName);
                        var pf2 = new PerformanceCounter("Process", "Working Set", p.ProcessName);
                        var WorkingSet = pf2.NextValue() / 1024 / 1024;
                        var WorkingSetPri = pf1.NextValue() / 1024 / 1024;
                        var WorkingSet64 = p.WorkingSet64 / 1024f / 1024f;
                        File.AppendAllText("data.csv",
                            string.Format("{3},{4},{0:f1},{1:f1},{2:f1}\r\n", WorkingSet64, WorkingSet, WorkingSetPri,
                                DateTime.Now.ToString("HH-mm-ss.fff"), ProInfo.ProcessName));
                        // Console.WriteLine("OK");
                        Thread.Sleep(1000);

                    }
                    catch (Exception exception)
                    {
                        CallRefresh();
                        break;

                    }
                }
               
            }
        }



        private void CancelClick(object sender, RoutedEventArgs e)
        {
            Worker.CancelAsync();
            CallRefresh();
        }
    }

    public class ProcessInfo
    {
        public string ProcessName { get; set; }
        public int Id { get; set; }
    }
}
